<?php

namespace Romolo\Snitso\Pcntl;


class Worker
{
    protected $socket;
    public $onConnect = null;
    public $onReceive = null;
    public $onClose = null;

    // 子进程个数
    private $workerNum = 4;

    public function __construct(string $address)
    {
        $this->socket = stream_socket_server($address);
    }

    public function start()
    {
        $this->fork();
    }

    private function fork()
    {
        $pidArr = [];

        for ($i = 0; $i < $this->workerNum; $i++) {
            // 创建成功会返回子进程id
            $sonPid = pcntl_fork();

            if ($sonPid == 0) {
                // 子进程负责接收客户端请求
                $this->accept();

                exit;
            } elseif ($sonPid > 0) {
                // 父进程空间，返回子进程id
                $pidArr[] = $sonPid;
            } else {
                exit('创建失败' . PHP_EOL);
            }
        }

        while (count($pidArr) > 0) {
            foreach ($pidArr as $k => $pid) {
                // 等待或返回fork的子进程状态
                $res = pcntl_waitpid($pid, $status, WNOHANG);

                // 子进程早已退出
                if ($res == -1 || $res > 0) {
                    unset($pidArr[$k]);
                }
            }
        }
    }

    private function accept()
    {
        while (true) {
            $client = stream_socket_accept($this->socket);
            var_dump(posix_getpid() . PHP_EOL);
            ($this->onConnect)($this, $client);

            $data = fread($client, 65535);
            ($this->onReceive)($this, $client, $data);

            fclose($client);
        }
    }

    public function send($client, $data)
    {
        $response = "HTTP/1.1 200 OK\r\n";
        $response .= "Content-Type: text/html;charset=UTF-8\r\n";
        $response .= "Connection: keep-alive\r\n";
        $response .= "Content-length: ".strlen($data)."\r\n\r\n";
        $response .= $data;
        fwrite($client, $response);
    }
}